<template>
  <view v-if="showPopup" class="ui-popup" @touchmove.stop.prevent="clear">
    <!-- 遮罩层 -->
    <uiTransition
      :mode-class="['fade']"
      :styles="maskClass"
      :duration="duration"
      :show="showTrans"
      @click="handleClickOverlay"
      v-if="overlay"
    />
    <uiTransition
      :mode-class="ani"
      :styles="transClass"
      :duration="duration"
      :show="showTrans"
      @click="onTap"
    >
      <view class="ui-popup--wrapper" :class="popupWrapperClass" @click.stop="clear">
        <slot />
        <uiIcon
          :name="closeIcon"
          class="ui-popup--close"
          :class="[`is-${closeIconPosition}`]"
          v-if="closeable"
          @click="handleClickCloseIcon"
        ></uiIcon>
      </view>
    </uiTransition>
  </view>
</template>

<script>
import uiTransition from "@/components/base/transition/index.vue";
import uiIcon from "@/components/base/icon/index.vue";

export default {
  name: "UniPopup",
  components: {
    uiTransition,
    uiIcon
  },
  props: {
    customClass: {
      type: String,
      default: ""
    },
    // 开启动画
    animation: {
      type: Boolean,
      default: true
    },

    // maskClick
    maskClick: {
      type: Boolean,
      default: true
    },

    // 是否显示圆角
    round: Boolean,

    customStyle: String,
    overlayStyle: String,
    transition: {
      type: String
    },
    zIndex: {
      type: Number,
      value: 100
    },
    // 是否显示遮罩层
    overlay: {
      type: Boolean,
      default: true
    },

    // 是否显示关闭图标
    closeable: Boolean,

    // 关闭图标名称或图片链接
    closeIcon: {
      type: String,
      default: "ui-icon-cross"
    },
    // 关闭图标位置，可选值为top-left bottom-left bottom-right
    closeIconPosition: {
      type: String,
      default: "top-right"
    },

    // 是否在点击遮罩层后关闭
    closeOnClickOverlay: {
      type: Boolean,
      default: true
    },
    // 弹出位置，可选值为 top bottom right left
    position: {
      type: String,
      default: "center"
    },

    safeAreaInsetBottom: {
      type: Boolean,
      default: true
    },

    safeAreaInsetTop: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      duration: 300,
      ani: [],
      showPopup: false,
      showTrans: false,
      maskClass: {
        position: "fixed",
        bottom: 0,
        top: 0,
        left: 0,
        right: 0,
        backgroundColor: "rgba(0, 0, 0, 0.4)"
      },
      transClass: {
        position: "fixed",
        left: 0,
        right: 0
      }
    };
  },
  computed: {
    popupWrapperClass() {
      let popupClass = this.customClass ? `${this.customClass} ` : "";

      if (this.round) {
        popupClass += " is-round";
      }
      // 底部安全距离
      if (this.safeAreaInsetBottom) {
        popupClass += "safe-area-inset";
      }
      // 顶部安全距离
      if (this.safeAreaInsetTop) {
        popupClass += "safe-area-inset-top";
      }

      popupClass += ` is-${this.position}`;
      return popupClass;
    },
    popupWrapperStyle() {
      return `z-index : ${this.zIndex};-webkit-transition-duration:${
        this.currentDuration
      }ms; transition-duration:${this.currentDuration}ms;${
        this.display ? "display:none;" : ""
      }${this.customStyle}`;
    }
  },
  watch: {
    position: {
      handler: function(newVal) {
        switch (this.position) {
          case "top":
            this.ani = ["slide-top"];
            this.transClass = {
              position: "fixed",
              left: 0,
              right: 0
            };
            break;
          case "bottom":
            this.ani = ["slide-bottom"];
            this.transClass = {
              position: "fixed",
              left: 0,
              right: 0,
              bottom: 0
            };
            break;
          case "center":
            this.ani = ["zoom-out", "fade"];
            this.transClass = {
              position: "fixed",
              /* #ifndef APP-NVUE */
              display: "flex",
              flexDirection: "column",
              /* #endif */
              bottom: 0,
              left: 0,
              right: 0,
              top: 0,
              justifyContent: "center",
              alignItems: "center"
            };

            break;
        }
      },
      immediate: true
    }
  },
  created() {
    if (this.animation) {
      this.duration = 300;
    } else {
      this.duration = 0;
    }
  },
  methods: {
    clear(e) {
      // TODO nvue 取消冒泡
      e.stopPropagation();
    },
    open() {
      console.log("2");
      this.showPopup = true;
      this.$nextTick(() => {
        clearTimeout(this.timer);
        this.timer = setTimeout(() => {
          this.showTrans = true;
        }, 50);
      });
      this.$emit("change", {
        show: true
      });
    },
    close(type) {
      this.showTrans = false;
      this.$nextTick(() => {
        clearTimeout(this.timer);
        this.timer = setTimeout(() => {
          this.$emit("change", {
            show: false
          });
          this.showPopup = false;
        }, 300);
      });
    },

    /**
     * 点击遮罩层触发的事件
     */
    handleClickOverlay() {
      if (!this.overlay || !this.closeOnClickOverlay) return;
      this.close();
    },

    handleClickCloseIcon() {
      this.close();
    },
    onTap() {
      if (!this.maskClick) return;
      this.close();
    },

    observeClass() {
      const { transition, position } = this;

      if (transition === "none") {
        this.duration = 0;
      }

      this.name = transition || position;
    }
  }
};
</script>
<style lang="scss" scoped>
.ui-popup {
  position: fixed;
  /* #ifdef H5 */
  top: var(--window-top);
  /* #endif */
  /* #ifndef H5 */
  top: 0;
  /* #endif */
  bottom: 0;
  left: 0;
  right: 0;
  /* #ifndef APP-NVUE */
  z-index: 99;
  /* #endif */

  .ui-popup--wrapper {
    /* #ifndef APP-NVUE */
    display: block;
    /* #endif */
    position: relative;
    max-height: 100%;
    overflow-y: auto;
    background-color: #fff;

    padding: 60upx;

    &.is-top {
      border-radius: 0 0 20upx 20upx;
    }
    &.is-center {
      border-radius: 20upx 20upx;
    }
    &.is-bottom {
      border-radius: 20upx 20upx 0 0;

      &.safe-area-inset {
        padding-bottom: constant(safe-area-inset-bottom);
        padding-bottom: env(safe-area-inset-bottom);
      }
    }
    &.safe-area-inset-top {
      padding-top: constant(safe-area-inset-top);
      padding-top: env(safe-area-inset-top);
    }
    .ui-popup--close {
      position: absolute !important;
      &.is-top-left {
        top: 32upx;
        left: 32upx;
      }

      &.is-top-right {
        top: 32upx;
        right: 32upx;
      }
      &.is-bottom-left {
        bottom: 32upx;
        left: 32upx;
      }
      &.is-bottom-right {
        bottom: 32upx;
        right: 32upx;
      }
    }
  }
}

.uni-popup__mask {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  background-color: $fill-mask;
  opacity: 0;
}

.mask-ani {
  transition-property: opacity;
  transition-duration: 0.2s;
}

.uni-top-mask {
  opacity: 1;
}

.uni-bottom-mask {
  opacity: 1;
}

.uni-center-mask {
  opacity: 1;
}

.uni-popup__wrapper {
  /* #ifndef APP-NVUE */
  display: block;
  /* #endif */
  position: absolute;
}

.top {
  top: 0;
  left: 0;
  right: 0;
  transform: translateY(-500px);
}

.bottom {
  bottom: 0;
  left: 0;
  right: 0;
  transform: translateY(500px);
}

.center {
  /* #ifndef APP-NVUE */
  display: flex;
  flex-direction: column;
  /* #endif */
  bottom: 0;
  left: 0;
  right: 0;
  top: 0;
  justify-content: center;
  align-items: center;
  transform: scale(1.2);
  opacity: 0;
}

.content-ani {
  // transition: transform 0.3s;
  transition-property: transform, opacity;
  transition-duration: 0.2s;
}

.uni-top-content {
  transform: translateY(0);
}

.uni-bottom-content {
  transform: translateY(0);
}

.uni-center-content {
  transform: scale(1);
  opacity: 1;
}
</style>
